
package com.grandstream.website.app.security.authorize;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.UrlMatcher;
import com.grandstream.website.app.security.enums.EmDbResourcetype;

/**  
 * 类描述：  
 * 创建人：Smile_zheng
 * 创建时间：2010-12-8 上午07:58:03  
 * 修改人：Smile_Zheng 
 * 修改时间：2010-12-8 上午07:58:03  
 * 修改备注：  
 * @version v 1.0
 *   
 */
public class DbUrlFilterInvocationMetadataSource implements FilterInvocationSecurityMetadataSource{
	public static final String DEFAULT_ROLE_RESC_URL_QUERY="select role.name,resc.rule from sys_resource resc ,sys_role role ,sys_role_resc role_resc " +
			"where resc.sysid =role_resc.resourceid and role.sysid=role_resc.roleid and resc.type='"+EmDbResourcetype.URL+"' " +
					"and resc.status='1' and role.status='1' and role_resc.status='1' order by resc.priority";
	
	private String role_resc_url_query;
	
	private JdbcTemplate jdbcTemplate;
	
	private UrlMatcher urlMatcher;
	
	public UrlMatcher getUrlMatcher() {
		return urlMatcher;
	}


	public void setUrlMatcher(UrlMatcher urlMatcher) {
		this.urlMatcher = urlMatcher;
	}


	public DbUrlFilterInvocationMetadataSource(){
		role_resc_url_query=DEFAULT_ROLE_RESC_URL_QUERY;
	}

	
	public java.util.List<Resource> getResourceList(){
		return jdbcTemplate.query(role_resc_url_query, new RowMapper<Resource>() {
				public Resource mapRow(ResultSet rs, int rowNum) throws SQLException {
					// TODO Auto-generated method stub
					Resource resource =new Resource();
					resource.rolename=rs.getString(1);
					resource.rule=rs.getString(2);
					return resource;
				}
			});
	}
	
/*	
 * public LinkedHashMap<RequestKey, Collection<ConfigAttribute>> getRequestMap(){
		LinkedHashMap<RequestKey, Collection<ConfigAttribute>> ResourceMap =new LinkedHashMap<RequestKey, Collection<ConfigAttribute>>();
		java.util.List<Resource> ResourceList=this.getResourceList();
		for(Resource res :ResourceList){
			RequestKey rk =new RequestKey(res.rule, null);
			ConfigAttribute cb =new SecurityConfig(res.rule);
			Collection<ConfigAttribute> collection =new ArrayList<ConfigAttribute>();
			collection.add(cb);
			ResourceMap.put(rk, collection);
		}
			return ResourceMap;
	}
	*/
	
	
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate=new JdbcTemplate(dataSource);
	}
	public String getRole_resc_url_query() {
		return role_resc_url_query;
	}
	public void setRole_resc_url_query(String role_resc_url_query) {
		this.role_resc_url_query = role_resc_url_query;
	}
	
	/* (non-Javadoc)  
	* @see org.springframework.security.access.SecurityMetadataSource#getAttributes(java.lang.Object)  
	*/
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		// TODO Auto-generated method stub
	    String url = ((FilterInvocation) object).getRequestUrl();
	    return lookupAttributes(url);
	}

	public final Collection<ConfigAttribute> lookupAttributes(String url) {
		Collection<ConfigAttribute> attributes =null;
            // Strip anything after a question mark symbol, as per SEC-161. See also SEC-321
            int firstQuestionMarkIndex = url.indexOf("?");

            if (firstQuestionMarkIndex != -1) {
                url = url.substring(0, firstQuestionMarkIndex);
            }
            url = url.toLowerCase();
            attributes = extractMatchingAttributes(url,this.getResourceList());

        return attributes;
    }

	private Collection<ConfigAttribute> extractMatchingAttributes(String url,java.util.List<Resource> ResourceList) {
        if (ResourceList == null) {
            return null;
        }
        
        for(Resource res :ResourceList){
        	String resurl =res.rule==null?null:res.rule.toLowerCase().trim();
        	boolean matched = urlMatcher.pathMatchesUrl(resurl, url);
        	if(matched){
        		Collection<ConfigAttribute> collection= new ArrayList();
        		collection.add(new SecurityConfig(res.rolename));
        		return collection;
        	}
        }

        return null;
    }
	/* (non-Javadoc)  
	* @see org.springframework.security.access.SecurityMetadataSource#getAllConfigAttributes()  
	*/
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)  
	* @see org.springframework.security.access.SecurityMetadataSource#supports(java.lang.Class)  
	*/
	public boolean supports(Class<?> clazz) {
		// TODO Auto-generated method stub
		return true;
	}
	private  class Resource{
		private String rolename;
		private String rule;
	}
}
